package top.magicpotato.sample.controller;

import javafx.application.Platform;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Side;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.util.Duration;
import org.pomo.toasterfx.model.ToastParameter;
import top.magicpotato.sample.component.ConnectionDbDialog;
import top.magicpotato.sample.component.DbOptMenu;
import top.magicpotato.sample.component.ToastBar;
import top.magicpotato.sample.pojo.record.ConnectionInfo;
import top.magicpotato.sample.pojo.record.MybatisGenBaseInfo;
import top.magicpotato.sample.pojo.record.MybatisGenTableInfo;
import top.magicpotato.sample.service.MainService;
import top.magicpotato.sample.store.DbStore;
import top.magicpotato.sample.store.ProjectStore;

import java.io.File;
import java.net.URL;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;

public class MainController implements Initializable {

    @FXML
    private ResourceBundle resources;

    @FXML
    private VBox main;

    @FXML
    private TreeView<String> dbTreeView;

    @FXML
    private TreeItem<String> dbTreeRootItem;

    @FXML
    private TextField targetProject;

    @FXML
    private TextField modulePackage;

    @FXML
    private TextField xmlPackage;

    @FXML
    private TextField mapperPackage;

    @FXML
    private TextField tableAlia;

    @FXML
    private CheckBox countByExample;

    @FXML
    private CheckBox selectByExample;

    @FXML
    private CheckBox deleteByExample;

    @FXML
    private CheckBox updateByExample;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        CompletableFuture.runAsync(() -> {
            // 初始化数据源配置
            DbStore.load();
            for (Map.Entry<String, ConnectionInfo> entry : DbStore.getStore().entrySet()) {
                Platform.runLater(() -> dbTreeRootItem.getChildren().add(new TreeItem<>(entry.getKey())));
            }
            // 初始化项目包配置
            ProjectStore.load();
            MybatisGenBaseInfo mybatisGenBaseInfo = ProjectStore.get();
            if (mybatisGenBaseInfo != null) {
                targetProject.setText(mybatisGenBaseInfo.targetProject());
                modulePackage.setText(mybatisGenBaseInfo.modulePackage());
                xmlPackage.setText(mybatisGenBaseInfo.xmlPackage());
                mapperPackage.setText(mybatisGenBaseInfo.mapperPackage());
            }
        });
    }

    /**
     * 保存配置
     */
    public void saveConfig() {
        MybatisGenBaseInfo mybatisGenBaseInfo = new MybatisGenBaseInfo(
                targetProject.getText(),
                modulePackage.getText(),
                xmlPackage.getText(),
                mapperPackage.getText()
        );
        ProjectStore.add(mybatisGenBaseInfo);
        ProjectStore.store();
        ToastBar.getInstant().success("提示", "操作成功", ToastParameter.builder().timeout(Duration.seconds(2)).build());
    }

    /**
     * 开始生成配置
     */
    public void generatorRun() {
        TreeItem<String> selectedItem = dbTreeView.getSelectionModel().getSelectedItem();

        if (selectedItem == null || selectedItem.getParent().getParent() == null) {
            ToastBar.getInstant().warn("提示", "请选择表", ToastParameter.builder().timeout(Duration.seconds(2)).build());
            return;
        }

        String NickName = selectedItem.getParent().getValue();
        String tableName = selectedItem.getValue();

        System.out.println(NickName);
        System.out.println(tableName);

        ConnectionInfo connectionInfo = DbStore.get(NickName);

        MybatisGenBaseInfo mybatisGenBaseInfo = new MybatisGenBaseInfo(
                targetProject.getText(),
                modulePackage.getText(),
                xmlPackage.getText(),
                mapperPackage.getText()
        );

        MybatisGenTableInfo mybatisGenTableInfo = new MybatisGenTableInfo(
                tableName,
                tableAlia.getText(),
                countByExample.isSelected(),
                selectByExample.isSelected(),
                deleteByExample.isSelected(),
                updateByExample.isSelected()
        );

        CompletableFuture.runAsync(() -> {
            boolean res = MainService.getInstance().mybatisGenerator(connectionInfo, mybatisGenBaseInfo, mybatisGenTableInfo);
            if (res) {
                ToastBar.getInstant().success("提示", "操作成功", ToastParameter.builder().timeout(Duration.seconds(2)).build());
            } else {
                ToastBar.getInstant().fail("提示", "操作失败", ToastParameter.builder().timeout(Duration.seconds(2)).build());
            }
        });

    }

    /**
     * 按钮添加数据库连接事件
     *
     * @param event
     */
    public void addDbConnection(Event event) {
        ConnectionDbDialog connectionDbDialog = ConnectionDbDialog.getInstance();
        Optional<ConnectionInfo> connectionInfo = connectionDbDialog.showAndWait();
        connectionInfo.ifPresent(info -> {
            // 连接信息存储起来
            DbStore.add(info);
            dbTreeRootItem.getChildren().add(new TreeItem<>(info.nickName()));
            ToastBar.getInstant().success("提示", "添加数据库成功", ToastParameter.builder().timeout(Duration.seconds(2)).build());
        });
    }

    /**
     * treeView鼠标点击事件
     *
     * @param event
     */
    public void dbOptMenu(MouseEvent event) {
        if (event.getClickCount() == 1 && event.getButton().equals(MouseButton.SECONDARY)) {
            // 右键事件
            rightClick(event);
            return;
        }
        // 左键双击加载数据库下的表
        if (event.getClickCount() == 2 && event.getButton().equals(MouseButton.PRIMARY)) {
            leftClick();
        }
    }

    private void leftClick() {
        // 双击为连接过时则连接
        TreeItem<String> selectedItem = dbTreeView.getSelectionModel().getSelectedItem();
        if (!dbTreeView.getRoot().getChildren().contains(selectedItem)) {
            // 只有根节点里的元素可以双击
            return;
        }
        if (selectedItem.getChildren().size() > 0) {
            return;
        }
        MainService.getInstance().initTableTree(selectedItem);
    }

    private void rightClick(MouseEvent event) {
        // 获取选中的节点
        TreeItem<String> selectedItem = dbTreeView.getSelectionModel().getSelectedItem();
        if (selectedItem == null) {
            // 未选中任何节点则无动作
            return;
        }
        if (selectedItem.getParent().getParent() != null) {
            // 只有根节点才可以选中
            return;
        }
        // 在选中的节点上弹出菜单
        DbOptMenu db = DbOptMenu.getInstance(dbTreeView);
        db.show(event.getPickResult().getIntersectedNode(), Side.BOTTOM, event.getX(), 0);
    }

    /**
     * 选择目录
     */
    public void chooseDir() {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        File file = directoryChooser.showDialog(main.getScene().getWindow());
        if (file == null) {
            return;
        }
        targetProject.setText(file.getAbsolutePath());
    }
}
